#ifndef LECTEURPHRASEAVECTABLE_H_
#define LECTEURPHRASEAVECTABLE_H_

#include "LecteurSymbole.h"
#include "TableSymboles.h"
#include <string>
using namespace std;


/*! \file LecteurPhraseAvecTable.h
    \brief La spécification de la classe LecteurPhraseAvecTable
    \author Cedric Vierne et Sergio Vasquez
    \date 18.04.2011
 */

/*! \class LecteurPhraseAvecTable
    \brief
 */
class LecteurPhraseAvecTable {
public:

    /*! \fn LecteurPhraseAvecTable(string nomFich)
        \brief  Construit un lecteur de phrase pour vérifier la syntaxe du programme dans le fichier nomFich.
        \param string nomFich
    */
	LecteurPhraseAvecTable(string nomFich);

    /*! \fn analyse()
        \brief  Si le contenu du fichier est conforme à la grammaire, cette méthode se termine normalement et affiche un message "Syntaxe correcte".
     * la table des symboles (ts) aura été construite. Sinon, le programme sera interrompu (exit).
        \param aucun
    */
	void analyse();

    /*! \fn TableSymboles getTs () { return ts;    }
        \brief accesseur
        \param aucun
     *  \return ts
    */
	inline TableSymboles getTs ()   { return ts; } // accesseur

private:

    /*! \fn LecteurSymbole ls
        \brief le lecteur de symboles utilisé pour analyser le fichier
    */
    LecteurSymbole ls;

    /*! \fn TableSymboles  ts
        \brief la table des symboles valués
    */
    TableSymboles  ts;


    // implémentation de la grammaire

   /*! \fn Noeud* arbre
        \brief l'arbre abstrait
    */
    Noeud* arbre;

    // implémentation de la grammaire

    /*! \fn void  programme()
        \brief  <programme> ::= debut <seqInst> fin FIN_FICHIER
    */
    void  programme();

    /*! \fn void  seqInst
        \brief  <seqInst> ::= <inst> ; { <inst> ; }
    */
    void  seqInst();

    /*! \fn void  inst();
        \brief <inst> ::= <affectation> | <instSi> | <instTq> | <instRepeter>
    */
    void  inst();

    /*! \fn  void  affectation()
        \brief <affectation> ::= <variable> = <expression>
    */
    void  affectation();

    /*! \fn void  expression()
        \brief  <expression> ::= <facteur> { <opAdd> <facteur> }
    */
    void  expression();

    /*! \fn void facteur()
        \brief <facteur> ::= <entier>  |  <variable>  |  - <facteur>  |  ( <expression> )
    */
    void facteur();

    /*! \fn void terme()
        \brief <terme>::=<facteur>{<oppMult><facteur>}
    */
    void terme();

    /*! \fn void opAdd()
        \brief <opAdd>:: = + | -
    */
    void opAdd();

    /*! \fn void oppMult()
        \brief l<opMult>::=* | /
    */
    void oppMult();

    /*! \fn  void expBoolOu()
        \brief <expBoolOu>::=<expBoolEt> {ou} <expBoolEt>}
    */
    void expBoolOu();

    /*! \fn void expBoolEt()
        \brief <expBoolEt>::=<expression> {et <expression>}
    */
    void expBoolEt();

    /*! \fn void relation()
        \brief <relation>::=<expresion>{<opRel><expression>}
    */
    void relation();

    /*! \fn void opRel()
        \brief <opRel>::= == | != | <= | < | > | >=
    */
    void opRel();

    /*! \fn void opUnaire()
        \brief <opUnaire>::= - | non
    */
    void opUnaire();

    /*! \fn void instSi()
        \brief <instSi> ::= si ( <expBool> ) <seqInst> { sinonsi ( <expBool> ) <seqInst> }[ sinon <seqInst> ] finsi
    */
    void instSi();

    /*! \fn void instTq()
        \brief <instTq> ::= tantque ( <expBool> ) <seqInst> fintantque
    */
    void instTq();

    /*! \fn void instRepeter()
        \brief <instRepeter> ::= repeter <seqInst> jusqua ( <expBool> )
    */
    void instRepeter();

    /*! \fn void instLire()
        \brief
    */
    void instLire();

    /*! \fn void instEcrire()
        \brief
    */
    void instEcrire();

    /*! \fn void instPour()
        \brief
    */
    void instPour();

    /*! \fn void instSwitchCase()
        \brief
    */
    void instSwitchCase();

    // outils pour se simplifier l'analyse syntaxique
    void testerSymCour (string ch);  // si symbole courant != ch, erreur : on arrete le programme, sinon rien
    void sauterSymCour (string ch);  // si symbole courant == ch, on passe au symbole suivant, sinon erreur : on arrete
    void erreur (string mess);      // affiche les message d'erreur mess et arrete le programme
};

#endif /* LECTEURPHRASEAVECTABLE_H_ */
